%{
    #include "syntax.tab.h"

    extern int failed;

    #define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno;

%}

%option yylineno
digit [0-9]
digits {digit}|[1-9]{digit}+
INT {digits}
oct [0-7]
octs {oct}|[1-7]{oct}+
OCT [+-]?0{octs}
hex [0-9a-fA-F]{2}
HEX [+-]?0x{hex}+
FLOAT [+-]?{digits}\.{digit}+
EXPO [+-]?{digits}\.{digit}+e[+-]?{digits}
letter [_a-zA-Z]
words {letter}+
ID {letter}({letter}|{digit})*
SEMI ;
COMMA ,
ASSIGNOP =
RELOP >|<|>=|<=|==|!=
PLUS \+
MINUS -
STAR \*
DIV \/
AND &&
OR \|\|
DOT \.
NOT !
TYPE int|float
LP \(
RP \)
LB \[
RB \]
LC \{
RC \}
STRUCT struct
RETURN return
IF if
ELSE else
WHILE while

%%
"//" {
    char ch; while((ch = input()) != '\n' && ch != NULL);
}
"/*" {
    char ch = input(); int done = 0; 
    while(done < 2 && ch != EOF && ch != NULL) {
        ch = input();
        if(ch == '*') done = 1;
        else if(ch == '/' && done == 1) done = 2;
        else done = 0;
    }
}
{INT} {
    yylval.nodeval = createLeaf(46, yylineno, yytext); return INT;
}
{OCT} {
    yylval.nodeval = createLeaf(46, yylineno, yytext); return INT;
}
{HEX} {
    yylval.nodeval = createLeaf(46, yylineno, yytext); return INT;
}
{FLOAT} {
    yylval.nodeval = createLeaf(47, yylineno, yytext); return FLOAT;
}
{EXPO} {
    yylval.nodeval = createLeaf(47, yylineno, yytext); return FLOAT;
}
{SEMI} {
    yylval.nodeval = createLeaf(21, yylineno, yytext); return SEMI;
}
{COMMA} {
    yylval.nodeval = createLeaf(22, yylineno, yytext); return COMMA;
}
{ASSIGNOP} {
    yylval.nodeval = createLeaf(36, yylineno, yytext); return ASSIGNOP;
}
{RELOP} {
    yylval.nodeval = createLeaf(40, yylineno, yytext); return RELOP;
}
{PLUS} {
    yylval.nodeval = createLeaf(41, yylineno, yytext); return PLUS;
}
{MINUS} {
    yylval.nodeval = createLeaf(42, yylineno, yytext); return MINUS;
}
{STAR} {
    yylval.nodeval = createLeaf(43, yylineno, yytext); return STAR;
}
{DIV} {
    yylval.nodeval = createLeaf(37, yylineno, yytext); return DIV;
}
{AND} {
    yylval.nodeval = createLeaf(38, yylineno, yytext); return AND;
}
{OR} {
    yylval.nodeval = createLeaf(39, yylineno, yytext); return OR;
}
{DOT} {
    yylval.nodeval = createLeaf(45, yylineno, yytext); return DOT;
}
{NOT} {
    yylval.nodeval = createLeaf(44, yylineno, yytext); return NOT;
}
{TYPE} {
    yylval.nodeval = createLeaf(23, yylineno, yytext); return TYPE;
}
{LP} {
    yylval.nodeval = createLeaf(30, yylineno, yytext); return LP;
}
{RP} {
    yylval.nodeval = createLeaf(31, yylineno, yytext); return RP;
}
{LB} {
    yylval.nodeval = createLeaf(28, yylineno, yytext); return LB;
}
{RB} {
    yylval.nodeval = createLeaf(29, yylineno, yytext); return RB;
}
{LC} {
    yylval.nodeval = createLeaf(25, yylineno, yytext); return LC;
}
{RC} {
    yylval.nodeval = createLeaf(26, yylineno, yytext); return RC;
}
{STRUCT} {
    yylval.nodeval = createLeaf(24, yylineno, yytext); return STRUCT;
}
{RETURN} {
    yylval.nodeval = createLeaf(32, yylineno, yytext); return RETURN;
}
{IF} {
    yylval.nodeval = createLeaf(33, yylineno, yytext); return IF;
}
{ELSE} {
    yylval.nodeval = createLeaf(34, yylineno, yytext); return ELSE;
}
{WHILE} {
    yylval.nodeval = createLeaf(35, yylineno, yytext); return WHILE;
}
{ID} {
    yylval.nodeval = createLeaf(27, yylineno, yytext); return ID;
}
[ \f\v\s\t\r\n] {}
. {
    failed = 1; 
    printf("Error type A at line %d: Mysterious characters \'%s\'\n", yylineno, yytext);
}

%%
